package com.tanhua.sso.service;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.tanhua.sso.mapper.UserMapper;
import com.tanhua.sso.pojo.User;
import io.jsonwebtoken.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.StringUtils;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.messaging.MessagingException;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

@Service
@Slf4j
public class UserService {

    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    @Autowired
    private UserMapper userMapper;

    @Value("${jwt.secret}")
    private String secret;

    @Autowired
    private RocketMQTemplate rocketMQTemplate;

    /**
     * @Description: 方法说明
     * @param: phone :手机号 code: 验证码
     * @return:
     * @Author: 熊佳杰
     * @Date: 2021/1/1
     */
    public String login(String phone, String code) {

        boolean isNew = false;//默认不是一个新用户
        String redisKey = "CHECK_CODE_" + phone;
        String redisData = redisTemplate.opsForValue().get(redisKey);//从Redis中获得验证码;
        System.out.println("redisData = " + redisData);
        if (!StringUtils.equals(code, redisData)) {//如果code和redis中保存的数据一致,取反后不一致,
            return null;//验证码错误
        }

        //验证码输入校验完成之后,需要废弃
        redisTemplate.delete(redisKey);
        //查询数据库
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("mobile", phone);
        User user = userMapper.selectOne(wrapper);
        //判断user是否为空,也就是判断数据库中是否注册过,没有就就注册一下
        if (null == user) {
            user = new User();
            user.setMobile(phone);
            user.setPassword(DigestUtils.md5Hex("000000"));
            userMapper.insert(user);
            isNew = true;//是一个新用户
        }

        //生成token
        Map<String, Object> claims = new HashMap<String, Object>();
        claims.put("id", user.getId());

        String token = Jwts.builder()
                // .setHeader(header)  //header，可省略
                .setClaims(claims) //payload，存放数据的位置，不能放置敏感数据，如：密码等
                .signWith(SignatureAlgorithm.HS256, secret) //设置加密方法和加密盐
                .setExpiration(new DateTime().plusHours(12).toDate()) //设置12小时后过期时间，3秒后过期
                .compact();

        try {
            Map<String, Object> msg = new HashMap<>();
            msg.put("id", user.getId());
            msg.put("date", System.currentTimeMillis());
            rocketMQTemplate.convertAndSend("tanhua-sso-login", msg);
        } catch (MessagingException e) {
            log.error("发送消息失败!! ");
        }
        return token + "|" + isNew;
    }

    public User queryUserByToken(String token) {
        try {
            // 通过token解析数据
            Map<String, Object> body = Jwts.parser()
                    .setSigningKey(secret)
                    .parseClaimsJws(token)
                    .getBody();
            User user = new User();
            user.setId(body.get("id").toString());
            String redisKey = "TANHUA_USER_MOBILE_" + user.getId();
            if (redisTemplate.hasKey(redisKey)) {
                //判断redis中是否存在mobile
                String mobile = redisTemplate.opsForValue().get(redisKey);
               // System.out.println(mobile);
                user.setMobile(mobile);
            } else {
                //不存在,查询数据库，获得mobile，将其存入redis中
                User u = userMapper.selectById(user.getId());
                long time = Long.valueOf(body.get("exp").toString()) * 1000 - System.currentTimeMillis();
                ;
                redisTemplate.opsForValue().set(redisKey, u.getMobile(),time);
            }
            return user;//根据token判断user是否存在
        } catch (ExpiredJwtException e) {
            //token失效
            log.info("token失效");
        } catch (Exception e) {
            //token不合法
          log.error("token不合法 token="+token,e);
        }
        return null;
    }
}
